<template>
  <a-spin :loading="loading">
    <template v-if="!wildCard">
      <!-- <a-alert v-if="applying"> 证书申请中，请耐心等待 </a-alert> -->
      <div v-if="applying" class="certificate-applying">
        <i-icons-applying class="rotate-infinite" /> 证书申请中，请耐心等待
      </div>
      <template v-else>
        <LicenseInfo v-if="hasLicenseInfo" :source="2" />
        <div v-else class="upload">
          <i-icons-no-cert :size="20" />
          <span class="text-3">
            当前无证书，您可以
            <span class="text-primary cursor-pointer" @click="applyLicense">
              申请证书
            </span>
          </span>
        </div>
      </template>
      <a-button
        v-if="isExpired || applyFailed"
        status="normal"
        type="outline"
        class="px-4! mt-4 w-fit"
        @click="applyLicense">
        重新申请
      </a-button>
    </template>
    <div v-else class="mode-two">
      <div class="mode-two-subtitle">
        <i-icons-exclamation-circle size="16px" color="#ADAFB2" />
        请前往域名
        {{ siteStore.siteInfo.domain }}
        对应的DNS服务商为域名添加如下解析记录，添加成功后请勿删除或修改。
      </div>
      <div class="form-table">
        <div class="form-table-item">
          <div class="form-table-key">记录类型</div>
          <div class="form-table-value font-bold">
            {{ cname?.type || '-' }}
          </div>
        </div>
        <div class="form-table-item">
          <div class="form-table-key">主机记录</div>
          <div class="form-table-value">
            <CopyField
              mouse-over
              :copy-text="truncationDomain(cname?.name || '-')"
              :content="truncationDomain(cname?.name || '-')">
              {{ cname?.name || '-' }}
            </CopyField>
          </div>
        </div>
        <div class="form-table-item">
          <div class="form-table-key">记录值</div>
          <div class="form-table-value">
            <CopyField mouse-over :content="cname?.target">
              {{ cname?.target || '-' }}
            </CopyField>
          </div>
        </div>
      </div>
      <div class="flex mt-2">
        <a-button
          v-if="firstVerify || (!firstVerify && !verifyPass)"
          status="normal"
          type="outline"
          class="px-4! w-fit"
          @click="verifyRecords">
          检测
        </a-button>
        <a-button
          v-if="!firstVerify && verifyPass"
          status="success"
          type="outline"
          class="px-4! w-fit">
          <i-icons-success /> 检测通过
        </a-button>
        <a-button
          v-if="showApplyBtn"
          status="normal"
          type="outline"
          class="px-4! w-fit ml-4"
          :disabled="!showApplyBtn || !verifyPass"
          @click="applyLicense">
          申请证书
        </a-button>
        <a-button
          v-if="applying"
          status="normal"
          type="outline"
          class="px-4! w-fit ml-4"
          disabled>
          <icon-loading />
          证书申请中
        </a-button>
        <div v-if="!success" class="flex items-center ml-4">
          <span class="flex gap-x-4 leading-22px truncate">
            <span class="font-bold text-#f53f3f">证书申请失败</span>
            <span class="cursor-pointer text-#ED3C3C" @click="openError"
              >错误详情</span
            >
          </span>
        </div>
      </div>
      <license-info
        v-if="!applying && hasLicenseInfo"
        :source="2"
        class="mt-4" />
    </div>
  </a-spin>
  <error-msg-dialog
    v-model="errorVisible"
    :error-text="licenseInfo?.platform_cert?.error_msg ?? ''" />
</template>
<script lang="ts" setup>
import type { SiteLicenseCname } from '@/apis/model/license'
import {
  getApiCertLookupCnameApi,
  getApiCertApi,
  postApiCertObtainApi
} from '@/apis/modules/license'
import { LICENSE_APPLY_STATUS } from '@/constants'
import { useSiteStore } from '@/stores/site'
import { useIntervalFn } from '@vueuse/core'
import LicenseInfo from './LicenseInfo.vue'
import ErrorMsgDialog from './ErrorMsgDialog.vue'
import { IconLoading } from '@arco-design/web-vue/es/icon'

const { visible: errorVisible, open: openError } = usePopup()
const cname = defineModel<SiteLicenseCname>('cname', { required: true })
const licenseInfo = inject(licenseInfoKey)
const success = computed(() => !licenseInfo?.platform_cert?.error_msg)
const route = useRoute()
const loading = ref(false)
const siteStore = useSiteStore()
const siteId = computed(() => route.params.id as string)
const emit = defineEmits(['reload'])
// 首次验证
const firstVerify = ref(true)

// 解析记录验证是否通过
const verifyPass = ref<boolean>(false)

// 获取证书申请id是否存在
const hasLicenseId = computed(() => {
  return (
    Number(licenseInfo?.value?.site_cert?.platform_cert_id) > 0 ||
    Number(licenseInfo?.value?.platform_cert?.id) > 0
  )
})

// 有id或错误消息视为有证书申请信息
const hasLicenseInfo = computed(
  () => hasLicenseId.value || licenseInfo?.value?.platform_cert?.error_msg
)

// 申请结果
const applyResult = ref<LICENSE_APPLY_STATUS>()

// 是否处于申请中状态
const applying = computed(() => {
  return applyResult.value === LICENSE_APPLY_STATUS.APPLYING
})

// 展示申请按钮
const showApplyBtn = computed(() => {
  const id = Number(licenseInfo?.value?.site_cert?.platform_cert_id || '0') // 已经成功申请过证书
  if (applying.value) {
    return false
  }
  // 证书存在,且未过期
  if (id > 0 && !isExpired.value) {
    return false
  }

  return true
})
// 是否为泛域名
const wildCard = computed(() => siteStore.siteInfo.domain.startsWith('*'))

// 申请失败
const applyFailed = computed(() => {
  return applyResult.value === LICENSE_APPLY_STATUS.FAILED
})
// 证书是否到期
const isExpired = computed(() => {
  const time1 = Math.floor(Date.now() / 1000)
  const time2 = licenseInfo?.value?.platform_cert?.expired_at ?? 0
  if (time2 > 0) {
    return time1 > time2
  }
  return false
})

const ApplyId = ref('') // 申请中或申请失败的证书id
const verifyRecords = () => {
  loading.value = true
  getApiCertLookupCnameApi({
    site_id: siteId.value,
    site_domain: siteStore.siteInfo.domain
  })
    .then((res) => {
      verifyPass.value = res.available ?? false
      if (!verifyPass.value) {
        ToastUtils.error('检测不通过，请检查配置或稍后重试')
      }
    })
    .finally(() => {
      firstVerify.value = false
      loading.value = false
    })
}
const applyLicense = () => {
  loading.value = true
  postApiCertObtainApi({ site_id: siteId.value })
    .then((res) => {
      ApplyId.value = res.id!
      applyResult.value = LICENSE_APPLY_STATUS.APPLYING
      resume()
      emit('reload', false)
    })
    .finally(() => {
      loading.value = false
    })
}

// function removeSubstring(str: string, substr: string) {
//   const pattern = new RegExp(substr.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g')
//   return str.replace(pattern, '')
// }

const truncationDomain = (cname: string) => {
  const parts = cname.split('.')
  if (parts.length <= 2) {
    return ''
  }
  parts.splice(parts.length - 2, 2)
  return parts.join('.')
}
const { pause, resume } = useIntervalFn(
  () => {
    getApplyResult()
  },
  3000,
  {
    immediate: false
  }
)
function getApplyResult() {
  const id = ApplyId.value
    ? ApplyId.value
    : licenseInfo?.value?.platform_cert?.id ?? ''
  getApiCertApi({ id })
    .then((res) => {
      applyResult.value = res.apply_result ?? LICENSE_APPLY_STATUS.UNKNOWN
      if (applyResult.value !== LICENSE_APPLY_STATUS.APPLYING) {
        emit('reload', false)
        pause()
      }
    })
    .catch(() => {
      pause()
    })
}

watch(
  () => licenseInfo?.value,
  (v) => {
    if (v?.platform_cert?.apply_result) {
      applyResult.value = v.platform_cert?.apply_result
    }
  },
  {
    immediate: true
  }
)

onMounted(() => {
  if (applying.value) {
    resume()
  }
})

watch(
  () => siteStore.siteInfo.id,
  () => {
    firstVerify.value = true
    verifyPass.value = false
  }
)
</script>
<style lang="less">
.upload {
  border: 1px dashed var(--color-border-4);
  @apply flex flex-col justify-center items-center p-4 gap-y-2 rounded-2;
}
.mode-two {
  border: 1px dashed var(--color-border-4);
  @apply flex flex-col p-4 gap-y-2 rounded-2;
  .mode-two-subtitle {
    display: flex;
    justify-content: start;
    align-items: center;
    gap: 4px;
    color: var(----2color-text-5, #8f959e);
    font-size: 14px;
    line-height: 22px; /* 157.143% */
  }
}

.form-table {
  border: 1px dashed var(--color-border-4);
  display: flex;
  padding: 16px;
  flex-direction: column;
  align-items: flex-start;
  gap: 16px;
  align-self: stretch;
  border-radius: 8px;
  .form-table-item {
    display: flex;
    align-items: center;
    gap: 16px;
    .form-table-key {
      width: 80px;
      flex-shrink: 0;
      color: var(----1color-text-4, #8f959e);
      font-size: 14px;
      line-height: 22px; /* 157.143% */
    }
    .form-table-value {
      overflow: hidden;
      width: 100%;
      color: var(---color-text-2, #393c40);
      text-overflow: ellipsis;
      font-size: 14px;
      line-height: 22px; /* 157.143% */
    }
  }
}

.certificate-applying {
  display: flex;
  padding: 16px;
  align-items: center;
  gap: 16px;
  align-self: stretch;
  border-radius: 8px;
  border: 1px dashed var(---color-border-4, #dfe2e5);
}
</style>
